﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;

namespace vJine.Core {
    public class CheckException : CoreException {
        public CheckException(string Msg, params object[] Args)
            : base(Msg, Args) {

        }
    }

    public class Check {
        public static bool IS(object V, Type Target, string Msg, params object[] Args) {
            bool Mathch =
                V != null && V.GetType() == Target;

            return Check.True(Mathch, Msg, Args);
        }

        public static bool IS(Type V, Type Target, string Msg, params object[] Args) {
            bool Mathch = V == Target;

            return Check.True(Mathch, Msg, Args);
        }

        public static bool NULL(bool Is, object V, string Msg, params object[] Args) {
            bool Mathch = Is ? V == null : V != null;

            return Check.True(Mathch, Msg, Args);
        }

        public static bool Range<T>(T V, T min, T max, string Msg, params object[] Args) where T : IComparable<T> {
            bool Match = V.CompareTo(min) >= 0 && V.CompareTo(max) <= 0;

            return Check.True(Match, Msg, Args);
        }

        public static bool Min<T>(T V, T min, string Msg, params object[] Args) where T : IComparable<T> {
            bool Match = V.CompareTo(min) >= 0;

            return Check.True(Match, Msg, Args);
        }

        public static bool Max<T>(T V, T min, T max, string Msg, params object[] Args) where T : IComparable<T> {
            bool Match = V.CompareTo(max) <= 0;

            return Check.True(Match, Msg, Args);
        }

        public static bool True(bool Condidion, string Msg, params object[] Args) {
            if (!Condidion && !string.IsNullOrEmpty(Msg)) {
                throw new CheckException(Msg, Args);
            }

            return Condidion;
        }

        public static bool False(bool Condition, string Msg, params object[] Args) {
            return Check.True(!Condition, Msg, Args);
        }

        public static bool Pattern(string V, string Pattern, string Msg, params object[] Args) {
            return Check.True(Regex.IsMatch(V, Pattern), Msg, Args);
        }
    }

    [AttributeUsage(AttributeTargets.Property | AttributeTargets.Parameter, AllowMultiple = true, Inherited = true)]
    public class CheckAttribute : Attribute {
        public CheckAttribute() {
            this.OnSet = true;
            this.OnGet = false;
        }
        /// <summary>
        /// 取值的值，默认为空（仅取值）
        /// </summary>
        public string Name { get; set; }

        public string Message { get; set; }

        public bool OnGet { get; set; }
        public bool OnSet { get; set; }
    }

    [AttributeUsage(AttributeTargets.Property | AttributeTargets.Parameter, AllowMultiple = true, Inherited = true)]
    public class CheckRangeAttribute : CheckAttribute {
        internal double Min { get; set; }
        internal double Max { get; set; }

        public CheckRangeAttribute(sbyte min, sbyte max) {
            this.Min = min;
            this.Max = max;
        }

        public CheckRangeAttribute(byte min, byte max) {
            this.Min = min;
            this.Max = max;
        }

        public CheckRangeAttribute(short min, short max) {
            this.Min = min;
            this.Max = max;
        }

        public CheckRangeAttribute(ushort min, ushort max) {
            this.Min = min;
            this.Max = max;
        }

        public CheckRangeAttribute(int min, int max) {
            this.Min = min;
            this.Max = max;
        }

        public CheckRangeAttribute(uint min, uint max) {
            this.Min = min;
            this.Max = max;
        }

        public CheckRangeAttribute(long min, long max) {
            this.Min = min;
            this.Max = max;
        }

        public CheckRangeAttribute(ulong min, ulong max) {
            this.Min = min;
            this.Max = max;
        }

        public CheckRangeAttribute(float min, float max) {
            this.Min = min;
            this.Max = max;
        }

        public CheckRangeAttribute(double min, double max) {
            this.Min = min;
            this.Max = max;
        }

        public CheckRangeAttribute(DateTime min, DateTime max) {
            this.Min = min.ToBinary();
            this.Max = max.ToBinary();
        }
    }

    [AttributeUsage(AttributeTargets.Property | AttributeTargets.Parameter, AllowMultiple = true, Inherited = true)]
    public class CheckPatternAttribute : CheckAttribute {
        string Pattern { get; set; }
        public CheckPatternAttribute(string Pattern) {
            this.Pattern = Pattern;
        }
    }

    [AttributeUsage(AttributeTargets.Property | AttributeTargets.Parameter, AllowMultiple = true, Inherited = true)]
    public class CheckListAttribute : CheckAttribute {
        public CheckListAttribute(params object[] V) {

        }
    }
}
